package queueFactory

import (
	"base/common/funs"
	"base/common/log"
	"base/common/queue/queueAbstruct"
	"context"
	"fmt"
	"github.com/rabbitmq/amqp091-go"
	"time"
)

type RabbitMqQueue struct {
	Conn     *amqp091.Connection
	Ch       *amqp091.Channel
	Data     *queueAbstruct.QueueObj
	JsonData string
}

func (r *RabbitMqQueue) New(q *queueAbstruct.QueueObj) *RabbitMqQueue {

	userName := funs.Env("rabbitMq.username")
	password := funs.Env("rabbitMq.password")
	ip := funs.Env("rabbitMq.ip")
	port := funs.Env("rabbitMq.port")
	url := fmt.Sprintf("amqp://%s:%s@%s:%s", userName, password, ip, port)

	// 连接 rabbitMq
	conn, err := amqp091.Dial(url)

	if err != nil {
		panic("rabbitMq连接失败：" + err.Error())
	}

	// 打开一个通道
	r.Ch, err = conn.Channel()

	//连接负值方便后期关闭
	r.Conn = conn

	//队列参数赋值
	r.Data = q

	return r

}

// 处理数据
func (r *RabbitMqQueue) MakeJson() *RabbitMqQueue {

	//获取格式化后得 json 字符串
	jsonSrt, err := funs.GetJsonData(r.Data)

	if err != nil {
		log.ELog("rabbitMq读取失败", map[string]any{
			"err": err.Error(),
		})
		panic("转换json 字符串失败")
	}

	r.JsonData = jsonSrt

	//获取队列名称
	r.Data.Name = queueAbstruct.GetQueueName(r.Data.Name)

	//声明队列
	_, err = r.Ch.QueueDeclare(r.Data.Name, false, false, false, false, nil)
	if err != nil {
		panic("rabbitMq声明队列失败")
	}

	return r
}

// 压入队列 并返回结果
func (r *RabbitMqQueue) Push() error {

	//声明上下文 函数结束时销毁
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	//压入数据
	body := []byte(r.JsonData)
	err := r.Ch.PublishWithContext(ctx, "", r.Data.Name, false, false, amqp091.Publishing{
		ContentType: "text/plain",
		Body:        body,
	})

	//关闭链接与频道链接
	r.Ch.Close()
	r.Conn.Close()

	return err

}

// 读取数据
func (r *RabbitMqQueue) ReadList(ch *chan string) {

	go func() {
		// 获取队列的消息
		msgs, err := r.Ch.Consume(
			queueAbstruct.GetQueueName(r.Data.Name), // 队列名
			"",                                      // 消费者
			true,                                    // 自动回复
			false,                                   // 专用
			false,                                   // 无局部
			false,                                   // 阻塞处理
			nil,                                     // 参数
		)
		if err != nil {
			log.ELog("rabbitMq读取失败", map[string]any{
				"err": err.Error(),
			})
		}

		for msg := range msgs {
			*ch <- string(msg.Body)
		}
	}()
}
